/*
 * Copyright (C) Francisco Morero Peyrona. All rights reserved.
 *
 * This software is published under the terms of Open Source
 * License version 1.1, a copy of which has been included with this
 * distribution in the License.txt file.
 */

package jdbcmanager.swing.table;

import java.util.*; 

import javax.swing.table.*;

/**
 * Creates a JTable based in 2 Vectors: one for the data values and the other for the head values.  
 *  
 * @author Francisco Morero Peyrona
 */
public class JxTableVector extends JxTable
{
   protected Vector vData = new Vector();
   protected Vector vHead = new Vector();
   
   private boolean bEditable = false;
   
   //-------------------------------------------------------------------------//
   
   /**
    * Class constructor
    */
   public JxTableVector()
   {
      this( null, null );
   }
   
   /**
    * Class constructor
    * 
    * @param vData
    * @param vHead
    */
   public JxTableVector( Vector vData, Vector vHead )
   {
      setModel( new TableVectorModel() );
      setRowSelectionMode( true );
      
      setHead( vHead );
      setData( vData );
   }
   
   /**
    * 
    * @param vRow
    */
   public void addRow( Vector vRow )
   {
      int nSize = this.vData.size();   // Because last element == size - 1
       
      this.vData.add( vRow );
      
      ((TableVectorModel) getModel()).fireTableRowsInserted( nSize, nSize );
   }
   
   /**
    * 
    * @return
    */
   public Vector getData()
   {
      return this.vData;
   }
   
   /**
    * 
    * @param vData
    */
   public void setData( Vector v )
   {
      if( v == null )
         setData( (Object[]) null );
      else
         setData( v.toArray() );
   }
   
   /**
    * 
    * @param aoData
    */
   public void setData( Object[] aoData )
   {
      this.vData.removeAllElements();

      if( aoData != null )
      {
         for( int n = 0; n < aoData.length; n++ )
            this.vData.add( aoData[n] );
      }
         
      ((TableVectorModel) getModel()).fireTableDataChanged();
      
      if( this.vData.size() > 0 )
         setRowSelectionInterval( 0, 0 );
   }
   
   /**
    * 
    * @return
    */
   public Vector getHead()
   {
      return this.vHead;
   }

   /**
    * 
    * @param vHead
    */
   public void setHead( Vector v )
   {
      if( v == null )
         setHead( (Object[]) null );
      else
         setHead( v.toArray() );
   }
   
   /**
    * 
    * @param aoHead
    */
   public void setHead( Object[] aoHead )
   {
      this.vHead.removeAllElements();

      if( aoHead != null )
      {
         for( int n = 0; n < aoHead.length; n++ )
            this.vHead.add( aoHead[n] );
      }
         
      ((TableVectorModel) getModel()).fireTableStructureChanged();
   }

   /**
    * 
    * @param bEditable
    */   
   public void setEditable( boolean bEditable )
   {
      this.bEditable = bEditable;
   }
   
   /**
    * 
    * @return
    */
   public boolean isEditable()
   {
      return this.bEditable;
   }
   
   /**
    * Traverses all table cheking for every row which is the longest item.
    * Then it is compared with column title length and the bigger of both 
    * is sat as width for the column.
    */
   public void adjustColumnsWidth()
   {
      for( int nCol = 0; nCol < this.vHead.size(); nCol++ )
      {
         Object objCol    = this.vHead.get( nCol );
         int    nHeadSize = (objCol == null) ? 1 : ((String) objCol).length();
         int    nRowSize  = 0;
         
         for( int nRow = 0; nRow < this.vData.size(); nRow++ )
         {
            Object objRow = ((Vector) this.vData.get( nRow )).get( nCol );
            
            if( objRow != null )
            {
               int nLen = objRow.toString().length();
            
               if( nRowSize < nLen )
                  nRowSize = nLen;
            }
         }
         
         setColumnWidth( nCol, Math.max( nHeadSize, nRowSize ) + 3 );
      }
   }
   
   //-------------------------------------------------------------------------//
   // INNER CLASS: Table Model
   //-------------------------------------------------------------------------//
   
   protected class TableVectorModel extends AbstractTableModel
   {
      public String getColumnName( int nCol ) 
      {
         return (String) JxTableVector.this.vHead.get( nCol );   
      }
      
      public int getRowCount()
      {
         return JxTableVector.this.vData.size();
      }
      
      public int getColumnCount()
      {
         return JxTableVector.this.vHead.size();
      }
      
      public Object getValueAt( int nRow, int nCol )
      {
         Vector vRow = (Vector) JxTableVector.this.vData.get( nRow );
          
         return vRow.get( nCol );
      }

      public void setValueAt( Object oValue, int nRow, int nCol )
      {
         Vector vRow = (Vector) JxTableVector.this.vData.get( nRow );
         
         vRow.set( nCol, oValue );
      }
      
      public boolean isCellEditable( int nRow, int nCol )
      {
         return JxTableVector.this.bEditable;
      }
      
      // JTable uses this method to determine the default renderer/editor for each cell
      public Class getColumnClass( int nCol )
      {
         Object value = getValueAt( 0, nCol ); 
         return (value == null) ? String.class : value.getClass();
      }
   }
}